﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomSerializer.Tests
{
    public class SimpleTypesProperties : IComparable
    {
        public bool Bool { get; set; }
        public byte Byte { get; set; }
        public sbyte SByte { get; set; }
        public UInt16 UInt16 { get; set; }
        public UInt32 UInt32 { get; set; }
        public UInt64 UInt64 { get; set; }
        public Int16 Int16 { get; set; }
        public Int32 Int32 { get; set; }
        public Int64 Int64 { get; set; }
        public Single Single { get; set; }
        public Double Double { get; set; }
        public char Char { get; set; }
        public Guid Guid { get; set; }
        public DateTime DateTime { get; set; }
        public DateTime DateTimeUTC { get; set; }
        public DateTimeOffset DateTimeOffset { get; set; }
        public TimeSpan Timespan { get; set; }
        public string String { get; set; }
        public string StringNull { get; set; }
        public Decimal Decimal { get; set; }
        public byte[] Array { get; set; }

        public SimpleTypesProperties() { }

        public SimpleTypesProperties(bool init)
        {
            if (!init) return;

            Random r = new Random((int)(DateTime.Now.Ticks % int.MaxValue));

            Bool = r.Next(5) % 2 > 0;
            Byte = (byte)r.Next(255);
            SByte = (sbyte)(r.Next(250) - 128);

            UInt16 = (UInt16)r.Next(UInt16.MaxValue);
            Int16 = (Int16)(r.Next(Int16.MaxValue) - Int16.MaxValue / 2);

            UInt32 = (UInt32)r.Next(int.MaxValue);
            Int32 = r.Next(int.MaxValue) - int.MaxValue / 2;

            UInt64 = (UInt64)(((Int64)r.Next(int.MaxValue)) * r.Next(int.MaxValue));
            Int64 = ((Int64)r.Next(int.MaxValue)) * r.Next(int.MaxValue);

            Single = r.Next(int.MaxValue);
            Double = r.Next(int.MaxValue);
            Char = 'Ы';

            Guid = new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray());
            DateTime = new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31));
            DateTimeUTC = new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31));
            DateTimeOffset = new DateTimeOffset(DateTime.Ticks, TimeSpan.FromHours(r.Next(8)));
            Timespan = DateTime.Subtract(DateTime.Date);
            Decimal = new decimal(r.Next(int.MaxValue));
            Array = Enumerable.Range(0, r.Next(200)).Select(p => (byte)p).ToArray();
            String = "Тест Test";
        }

        public int CompareTo(object o)
        {
            var r = o as SimpleTypesProperties;
            return Bool == r.Bool
                   && Byte == r.Byte && SByte == r.SByte
                   && UInt16 == r.UInt16 && Int16 == r.Int16
                   && UInt32 == r.UInt32 && Int32 == r.Int32
                   && UInt64 == r.UInt64 && Int64 == r.Int64
                   && Single == r.Single && Double == r.Double
                   && Char == r.Char && Guid.CompareTo(r.Guid) == 0
                   && DateTime == r.DateTime
                   && DateTimeUTC == r.DateTimeUTC
                   && DateTimeOffset == r.DateTimeOffset
                   && Timespan == r.Timespan
                   && ((String == null && r.String == null) || string.Compare(String, r.String, false) == 0)
                   && (StringNull == null && r.StringNull == null)
                   && (Decimal == r.Decimal)
                ? 0 : 1;
        }
    }

    public class SimpleTypesNullablePropertes : IComparable
    {
        public bool? Bool { get; set; }
        public byte? Byte { get; set; }
        public sbyte? SByte { get; set; }
        public UInt16? UInt16 { get; set; }
        public UInt32? UInt32 { get; set; }
        public UInt64? UInt64 { get; set; }
        public Int16? Int16 { get; set; }
        public Int32? Int32 { get; set; }
        public Int64? Int64 { get; set; }
        public Single? Single { get; set; }
        public Double? Double { get; set; }
        public char? Char { get; set; }
        public Guid? Guid { get; set; }
        public DateTime? DateTime { get; set; }
        public DateTime DateTimeUTC { get; set; }
        public DateTimeOffset? DateTimeOffset { get; set; }
        public Decimal? Decimal { get; set; }
        public TimeSpan? Timespan { get; set; }

        public SimpleTypesNullablePropertes() { }

        public SimpleTypesNullablePropertes(bool init)
        {
            if (!init) return;

            Random r = new Random((int)(System.DateTime.Now.Ticks % int.MaxValue));

            Bool = r.Next(5) % 2 > 0;
            Byte = (byte)r.Next(255);
            SByte = (sbyte)(r.Next(250) - 128);

            UInt16 = (UInt16)r.Next(System.UInt16.MaxValue);
            Int16 = (Int16)(r.Next(System.Int16.MaxValue) - System.Int16.MaxValue / 2);

            UInt32 = (UInt32)r.Next(int.MaxValue);
            Int32 = r.Next(int.MaxValue) - int.MaxValue / 2;

            UInt64 = (UInt64)(((Int64)r.Next(int.MaxValue)) * r.Next(int.MaxValue));
            Int64 = ((Int64)r.Next(int.MaxValue)) * r.Next(int.MaxValue);

            Single = r.Next(int.MaxValue);
            Double = r.Next(int.MaxValue);
            Char = 'Ы';

            Guid = new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray());
            DateTime = new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31));
            DateTimeUTC = new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31));
            DateTimeOffset = new DateTimeOffset(DateTime.Value.Ticks, TimeSpan.FromHours(r.Next(8)));
            Timespan = DateTime.Value.Subtract(DateTime.Value.Date);

            Decimal = new decimal(r.Next(int.MaxValue));
        }

        int IComparable.CompareTo(object o)
        {
            var r = o as SimpleTypesNullablePropertes;
            return ((Bool == null && r.Bool == null) || Bool == r.Bool)
                   && ((Byte == null && r.Byte == null) || Byte == r.Byte)

                   && ((Int16 == null && r.Int16 == null) || Int16 == r.Int16)
                   && ((Int32 == null && r.Int32 == null) || Int32 == r.Int32)
                   && ((Int64 == null && r.Int64 == null) || Int64 == r.Int64)

                   && ((UInt16 == null && r.UInt16 == null) || UInt16 == r.UInt16)
                   && ((UInt32 == null && r.UInt32 == null) || UInt32 == r.UInt32)
                   && ((UInt64 == null && r.UInt64 == null) || UInt64 == r.UInt64)

                   && ((Single == null && r.Single == null) || Single == r.Single)
                   && ((Double == null && r.Double == null) || Double == r.Double)
                   && ((Char == null && r.Char == null) || Char == r.Char)
                   && ((DateTime == null && r.DateTime == null) || DateTime == r.DateTime)
                   && ((DateTimeOffset == null && r.DateTimeOffset == null) || DateTimeOffset == r.DateTimeOffset)
                   && ((Timespan == null && r.Timespan == null) || Timespan == r.Timespan)
                   && ((Decimal == null && r.Decimal == null) || Decimal == r.Decimal)
                ? 0 : 1;
        }
    }
}